package com.ygqh.baby.controller.mobile;

import com.fasterxml.jackson.databind.util.JSONPObject;
import com.foxinmy.weixin4j.mp.model.OauthToken;
import com.foxinmy.weixin4j.payment.PayRequest;
import com.foxinmy.weixin4j.type.TradeType;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.Constant;
import com.ygqh.baby.po.YgAccountDetail;
import com.ygqh.baby.po.YgUser;
import com.ygqh.baby.po.YgUserBalance;
import com.ygqh.baby.service.*;
import com.ygqh.baby.service.impl.DocumentConstant;
import com.ygqh.baby.service.wechat.YgWeChatService;
import com.ygqh.baby.service.wechat.protocol.UnifiedOrderReqData;
import com.ygqh.baby.utils.ExceptionUtil;
import com.ygqh.baby.utils.SessionUtil;
import com.ygqh.baby.utils.WebUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Objects;

/**
 * 虚拟账户
 *
 * @author guohao
 */
@Controller
@RequestMapping("/mobile/account")
public class YgVirtualAccountController extends BaseController {
    protected final Logger logger = Logger.getLogger(this.getClass());

    @Autowired
    private YgUserService userService;
    @Autowired
    private WxMpAuthorityService wxMpAuthorityService;
    @Autowired
    private YgFrameCodeService ygFrameCodeService;
    @Autowired
    private DocumentConstant documentConstant;
    @Autowired
    private YgOrderLogService ygOrderLogService;
    @Autowired
    private YgUserBalanceService ygUserBalanceService;
    @Value("${micro.msg.appId}")
    private String appid;
    @Value("${wechat.pay.mchid}")
    private String mchid;
    @Value("${micro.msg.secret}")
    private String appsecret;
    @Value("${wechat.pay.notify_url}")
    private String notify_url;
    @Value("${wechat.pay.recharge.notify_url}")
    private String recharge_notify_url;
    @Value("${wechat.pay.key}")
    private String key;
    @Autowired
    private YgWeChatService weChatService;
    @Autowired
    private YgAccountDetailService accountDetailService;
    @Autowired
    private YgRechargeMemberRecordService ygRechargeMemberRecordService;
    @Autowired
    private YgUserMemberService ygUserMemberService;
    @Autowired
    private YgUserService ygUserService;

    @RequestMapping(value = "getMyAccount")
    @ResponseBody
    public JSONPObject getMyAccount(String callback) {
        JSONPObject json = null;
        YgUser user = SessionUtil.getCurrentUser();
        YgUserBalance balance = ygUserBalanceService.findByUserId(user.getId());
        json = new JSONPObject(callback, Message.success(balance.getBalancePrice()));
        return json;
    }

    /**
     * 虚拟账户
     *
     * @param code
     * @param paymentCode
     * @param rechargePrice
     * @param rechargeType
     * @param cardIds
     * @param birthday
     * @param sourceCode
     * @param callback
     * @param request
     * @return
     */
    @RequestMapping(value = "recharge")
    @ResponseBody
    public JSONPObject unifiedOrder(String code, Long paymentCode, BigDecimal rechargePrice, CodeType rechargeType,
                                    String cardIds, Date birthday, String sourceCode, String callback,
                                    HttpServletRequest request) {

        YgUser user = SessionUtil.getCurrentUser();
        if (UserType.Distributor.equals(user.getUserType())) {
            return new JSONPObject(callback, Message.error("分销员不能购买女王", null));
        }
        if (CodeType.RechargeAG.equals(rechargeType) && ygUserService.isUserAgent(user.getId())) {
            return new JSONPObject(callback, Message.error("亲，您已经是壹家店会员，无需购买。", null));
        }
        Message msg;
        String openid;
        String ipAddress = WebUtils.getIpAddr(request);
        String[] split = ipAddress.split(",");
        ipAddress = split[0];
        PayRequest payRequest;
        String attach = user.getId() + "-" + rechargeType;
        // 生成支付流水

        if (rechargeType.equals(CodeType.RechargeMB)) {
            rechargePrice = ygUserMemberService.getVipPrice();
            /*attach = attach + "-" + cardIds + "-" + birthday.getTime();*/
            paymentCode = ygFrameCodeService.getFrameCode(rechargeType, new Date());
        } else {
            paymentCode = ygFrameCodeService.getFrameCode(rechargeType, new Date());

        }

        try {

            if (StringUtils.isNotEmpty(code)) {
                OauthToken oauthToken = wxMpAuthorityService.findOauthToken(code);
                openid = oauthToken.getOpenId();
                userService.bindingOpenId(user.getId(), openid, null, oauthToken.getUnionId());
            } else {
                if (user.getOpenId() == null) {
                    user = userService.findById(user.getId());
                }
                openid = user.getOpenId();
            }

            UnifiedOrderReqData reqData = new UnifiedOrderReqData.UnifiedOrderReqDataBuilder(appid, mchid, "壹果充值", paymentCode.toString(),
                    rechargePrice.multiply(new BigDecimal(100)).intValue(), ipAddress, recharge_notify_url, TradeType.JSAPI.name()).setAttach(attach)
                    .setOpenid(openid).build();
            msg = weChatService.UnifiedOrderJSAPI(reqData);
            if (msg.getType().equals(Message.Type.error)) {
                return new JSONPObject(callback, Message.error(documentConstant.MESSAGE_ERROR, msg));
            }
            payRequest = (PayRequest) msg.getExtra();
            payRequest.setPartnerId(paymentCode.toString());

            // 充值会员
            if (CodeType.RechargeMB.equals(rechargeType) || CodeType.RechargeAG.equals(rechargeType)) {
                ygRechargeMemberRecordService.addRecord(user.getId(), paymentCode, rechargePrice, "Year",
                        PayType.WeChat, AppType.WeChat, sourceCode, rechargeType, Constant.YIIGOO_PLATFORM_NO);
            }
        } catch (Exception e) {
            logger.error(rechargeType.getTitle() + "执行失败，paymentCode =" + paymentCode + ";" + ExceptionUtil.getExceptionMsg(e));
            e.printStackTrace();
            return new JSONPObject(callback, Message.error(documentConstant.MESSAGE_ERROR, null));
        }
        return new JSONPObject(callback, Message.success(payRequest));
    }

    /**
     * 微信充值回调
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping(value = "rechargeCallBack")
    @ResponseBody
    public void rechargeCallBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setHeader("Content-type", "text/html;charset=UTF-8");
        ServletInputStream in = request.getInputStream();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        logger.debug("微信充值支付回调===================================");
        String result = new String(out.toByteArray(), "UTF-8");
        ygOrderLogService.addOrderLog(10l, OrderStatus.WaitingSend, "系统", "微信充值支付回调，回调数据 【" + result + "】;");
        String res = weChatService.rechargeCallBack(result);
        ygOrderLogService.addOrderLog(10l, OrderStatus.WaitingSend, "系统", "微信充值支付回调，返回微信数据 【" + res + "】;");
        logger.debug("\n微信充值支付回调返回结果：\n" + res);
        out.close();
        in.close();
        response.getWriter().print(res);
    }

    /**
     * 查找充值记录
     *
     * @param queryInfo
     * @return
     */
    @RequestMapping("searchDetailByUser")
    @ResponseBody
    public JSONPObject searchDetailByUser(QueryInfo queryInfo, String callback) {
        String username = Objects.requireNonNull(SessionUtil.getCurrentUser()).getUserName();
        ResultSet<YgAccountDetail> resultSet = accountDetailService.searchDetailByUser(queryInfo, username, null, null, null, null);
        JSONPObject json = new JSONPObject(callback, Message.success(documentConstant.MESSAGE_SUCCESS, resultSet));
        return json;

    }

}
